package main

import (
	"gzginwebsocket/ws"
	"net/http"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

var (
	//设置允许跨域
	upgrade = websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
)

func main() {

	r := gin.Default()

	r.GET("/ws", wsHandle)
	r.GET("/ws2", wsHandle2)
	r.Run()
}

//wsHandle 简单的websocket示例，客户端发送什么就返回什么
func wsHandle(c *gin.Context) {
	var (
		conn *websocket.Conn
		err  error
		// msgType int
		data []byte
	)
	//设置应答对象和请求对象并获取连接
	if conn, err = upgrade.Upgrade(c.Writer, c.Request, nil); err != nil {
		return
	}

	for {
		//websocket数据体有text和二进制Binary类型
		//读取数据体，ReadMessage返回数据体类型 数据 错误
		if _, data, err = conn.ReadMessage(); err != nil {
			goto ERR
		}
		//写入数据，传入类型和数据，websocket.TextMessage是常量表示text类型
		if err = conn.WriteMessage(websocket.TextMessage, data); err != nil {
			goto ERR
		}
	}
ERR:
	conn.Close()

}

//wsHandle2 线程安全的websocket，功能与上面一样，对收发进行了封装并且是线程安全
func wsHandle2(c *gin.Context) {
	var (
		wsConn *websocket.Conn
		err    error
		data   []byte
		conn   *ws.Connection
	)
	//设置应答对象和请求对象并获取连接
	if wsConn, err = upgrade.Upgrade(c.Writer, c.Request, nil); err != nil {
		return
	}
	//获取封装好的连接对象
	if conn, err = ws.InitConnection(wsConn); err != nil {
		goto ERR
	}

	//另起一个协程，每隔一秒发送心跳信息
	go func() {
		var (
			err error
		)
		for {
			if err = conn.WriteMessage([]byte("dokidoki")); err != nil {
				return
			}
			time.Sleep(1 * time.Second)
		}
	}()

	//还是收什么就发什么
	for {
		if data, err = conn.ReadMessage(); err != nil {
			goto ERR
		}
		if err = conn.WriteMessage(data); err != nil {
			goto ERR
		}
	}

ERR:
	conn.Close()
}
